17. Exercise: Stream API

Your company, Udacisearch, maintains a database of all its clients, each of which is represented by a UdacisearchClient instance.

There is a simple Java program, SummarizeClients, that computes some basic summary information using all the information from the clients. The code is a little old fashioned — it uses a for loop across all the client data to compute the summary. Your job is to refactor SummarizeClients to use the Java Stream API.

The starter code contains the old for-loop-based version of the program. The new code should have a single Stream-based computation for each of the following pieces of summary metrics:

  • totalQuarterlySpend - The sum of all clients' quarterly budgets.
  • averageBudget - The arithmetic mean of all clients' quarterly budgets. Hint: The average() method will be helpful.
  • nextExpiration - The id of the client whose contract is next to expire. Since this variable has type long, if you find yourself assigning a default value to this using the orElse() method, make sure your default value uses a long literal such as -1L instead of just -1.
  • representedZoneIds - The collection of all time zones where any clients are located. Hint: Stream#flatMap()) will be helpful.
  • contractsPerYear - A map whose keys are a java.time.Year, and whose values are the number of contracts starting in that year. Hint: Collectors.groupingBy(...) will be helpful.

Each metric should use the .stream() method to start off, and should use only intermediate and terminal Stream operations to compute the result. To get you started, here is one way to compute totalQuarterlySpend:

int totalQuarterlySpend =
    clients
        .stream()
        .mapToInt(UdacisearchClient::getQuarterlyBudget)
        .sum();

Note: This example uses a new line of code for each stream operation. You don't have to do that if you don't want — do whatever looks readable to you!

When you're done, try compiling and running the code:

javac SummarizeClients.java
java SummarizeClients

The output should look similar to this:

Num clients: 4
Total quarterly spend: 27500
Average budget: 6875.0
ID of next expiring contract: 1
Client time zones: [America/Los_Angeles, America/Denver, America/Tijuana, Asia/Manila, Asia/Bangkok, Australia/NSW, Australia/Melbourne]
Contracts per year: {2017=2, 2019=2}

TODO List

Task List:

Task Feedback:

Nice work! You successfully crunched the numbers using Java's Stream API!

Code

If you need a code on the https://github.com/udacity.

  • userCode:

    export PATH=/data/jdk-15.0.1/bin:$PATH
    export JAVA_HOME=/data/jdk-15.0.1/bin